package com.byq.mm.foundation.cluster.client;

import java.util.HashMap;
import java.util.Map;

import com.byq.mm.abstractx.cluster.client.ClusterClient;
import com.byq.mm.abstractx.cluster.provider.ClusterProvider;
import com.byq.mm.abstractx.device.Device;
import com.byq.mm.abstractx.engine.CoreEnvironment;
import com.byq.mm.abstractx.protocol.Interaction;


import com.byq.mm.foundation.cluster.client.event.AttributeEvent;
import com.byq.mm.foundation.cluster.client.event.SubscribeEvent;
import com.byq.mm.foundation.cluster.datatype.AttributeValue;
import com.byq.mm.foundation.cluster.datatype.AttributeValueFactory;


abstract public class BasicClusterClient extends ClusterClient {

	protected Map<String, AttributeValue> attributes = new HashMap<String, AttributeValue>();
	protected Map<String, Boolean> subscribed = new HashMap<String, Boolean>();
	protected abstract Class<? extends AttributeValue> getAttributeType(String attributeName);
	public BasicClusterClient(String cluster, Device device, CoreEnvironment e) {
		super(cluster, device, e);
	init();
		
	}
	
	
	abstract protected void init();


	@Override
	public boolean onReport(Interaction i) {
		if (i.command
				.equals(ClusterProvider.Define.ServerCommand.ReportAttribute.COMMAND_NAME)) {
			String attributeName = i.attributes.get(ClusterProvider.Define.ServerCommand.ReportAttribute.Parameters.ATTRIBUTE_NAME);
			String attributeValue = i.attributes.get(attributeName);
			AttributeValue value = AttributeValueFactory.decode(getAttributeType(attributeName),attributeValue);
			attributes.put(attributeName, value);
			env.getEventCenter().notifyClusterChange(getDevice().getGlobalId(), getCluster(), new AttributeEvent(this.getDevice().getGlobalId(), this.getCluster(),attributeName));
			return true;
		}
		if (i.command
				.equals(ClusterProvider.Define.ServerCommand.ReportSubscribe.COMMAND_NAME)) {
			String attributeName = i.attributes.get(ClusterProvider.Define.ServerCommand.ReportSubscribe.Parameters.ATTRIBUTE_NAME);
			
			String ss  = i.attributes.get(ClusterProvider.Define.ServerCommand.ReportSubscribe.Parameters.SUBSCRIBED);
			this.subscribed.put(attributeName, Boolean.parseBoolean(ss));
			env.getEventCenter().notifyClusterChange(getDevice().getGlobalId(), getCluster(), new SubscribeEvent(this.getDevice().getGlobalId(), this.getCluster(),this.getDevice().getId(), attributeName));
		}
		return false;

	}

	public void readAttribute(String attributeName) {
		Interaction i = createRequest();
		i.command = ClusterProvider.Define.ClientCommand.ReadAttribute.COMMAND_NAME;
		i.attributes.put(ClusterProvider.Define.ClientCommand.ReadAttribute.Parameters.ATTRIBUTE_NAME, attributeName);
		env.getExtensionManager().sendInteraction(i,
				getDevice().getTransportId());
	}
	public void writeAttribute(String attributeName, AttributeValue v) {
		Interaction i = createRequest();
		i.command = ClusterProvider.Define.ClientCommand.WriteAttribute.COMMAND_NAME;
		i.attributes.put(ClusterProvider.Define.ClientCommand.WriteAttribute.Parameters.ATTRIBUTE_NAME, attributeName);
		i.attributes.put(attributeName, v.encode());
		env.getExtensionManager().sendInteraction(i,
				getDevice().getTransportId());
	}
	public AttributeValue getAttributeValue(String attributeName) {
		return attributes.get(attributeName);
	}
	public void subscribe(String attributeName) {
		Interaction i = createRequest();
		i.command = ClusterProvider.Define.ClientCommand.Subscribe.COMMAND_NAME;
		i.attributes.put(ClusterProvider.Define.ClientCommand.Subscribe.Parameters.ATTRIBUTE_NAME, attributeName);
		env.getExtensionManager().sendInteraction(i,
				getDevice().getTransportId());

	}
	public void unsubscribe(String attributeName) {
		Interaction i = createRequest();
		i.command = ClusterProvider.Define.ClientCommand.Unsubscribe.COMMAND_NAME;
		i.attributes.put(ClusterProvider.Define.ClientCommand.Unsubscribe.Parameters.ATTRIBUTE_NAME, attributeName);
		env.getExtensionManager().sendInteraction(i,
				getDevice().getTransportId());
		

	}
	public boolean isSubscribed(String attributeName) {
		return subscribed.get(attributeName);
	}
	public void readSubscribe(String attributeName) {
		Interaction i = createRequest();
		i.command = ClusterProvider.Define.ClientCommand.ReadSubscribe.COMMAND_NAME;
		i.attributes.put(ClusterProvider.Define.ClientCommand.ReadSubscribe.Parameters.ATTRIBUTE_NAME, attributeName);
		env.getExtensionManager().sendInteraction(i,
				getDevice().getTransportId());
		
		}
	
}
